package com.lb.pdm.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lb.pdm.common.constants.RedisConstants;
import com.lb.pdm.common.result.GraceJSONResult;
import com.lb.pdm.entity.*;
import com.lb.pdm.entity.bo.BirthRegistrationBO;
import com.lb.pdm.mapper.BirthRegistrationMapper;
import com.lb.pdm.mapper.HouseholdInfoMapper;
import com.lb.pdm.mapper.HouseholdTransferMapper;
import com.lb.pdm.mapper.PersonInfoMapper;
import com.lb.pdm.service.BirthRegistrationService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.text.SimpleDateFormat;

/**
 * <p>
 * 出生申报表 服务实现类
 * </p>
 *
 * @author pdm
 * @since 2025-10-29
 */
@Service
public class BirthRegistrationServiceImpl extends ServiceImpl<BirthRegistrationMapper, BirthRegistration> implements BirthRegistrationService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private HouseholdInfoMapper householdInfoMapper;
    @Autowired
    private PersonInfoMapper personInfoMapper;
    @Autowired
    private HouseholdTransferMapper householdTransferMapper;

    @Override
    public GraceJSONResult birthRegister(BirthRegistrationBO birthRegistrationBO, String token) {
        BirthRegistration birthRegistration = new BirthRegistration();
        BeanUtils.copyProperties(birthRegistrationBO, birthRegistration);

        birthRegistration.setApplicationStatus((byte)1);
        birthRegistration.setCreateTime(new Date());
        birthRegistration.setUpdateTime(new Date());

        String sysUserStirng = redisTemplate.opsForValue().get(RedisConstants.USER_TOKEN_PREFIX + token);
        if (sysUserStirng.isEmpty()) {
            return GraceJSONResult.errorMsg("系统用户未登录");
        }

        SysUser sysUser = JSON.parseObject(sysUserStirng, SysUser.class);
        birthRegistration.setCreateBy(sysUser.getId());
        birthRegistration.setUpdateBy(sysUser.getId());

        PersonInfo personInfo = new PersonInfo();
        personInfo.setName(birthRegistrationBO.getChildName());
        personInfo.setGender(birthRegistrationBO.getChildGender());
        personInfo.setBirthDate(birthRegistrationBO.getBirthDate());

        Long targetHouseholdId = birthRegistrationBO.getTargetHouseholdId();
        LambdaQueryWrapper<HouseholdInfo> householdInfoQuery = new LambdaQueryWrapper<>();
        householdInfoQuery.eq(HouseholdInfo::getId, targetHouseholdId);
        // 目的户籍
        HouseholdInfo householdInfo = householdInfoMapper.selectOne(householdInfoQuery);

        if (householdInfo == null) {
            return GraceJSONResult.errorMsg("目标户籍不存在");
        }

        // 目的户籍的户主人员id
        Long householderId = householdInfo.getHouseholderId();
        LambdaQueryWrapper<PersonInfo> personInfoQuery = new LambdaQueryWrapper<>();
        personInfoQuery.eq(PersonInfo::getId, householderId);
        PersonInfo houseHolderPersonInfo = personInfoMapper.selectOne(personInfoQuery);

        if (houseHolderPersonInfo == null) {
            return GraceJSONResult.errorMsg("户主不存在");
        }

        personInfo.setNationality(houseHolderPersonInfo.getNationality());
        personInfo.setEthnicity(houseHolderPersonInfo.getEthnicity());
        personInfo.setMaritalStatus((byte) 1);
        personInfo.setStatus((byte)1);
        personInfo.setCreateTime(new Date());
        personInfo.setUpdateTime(new Date());
        personInfo.setCreateBy(sysUser.getId());
        personInfo.setUpdateBy(sysUser.getId());

        String stationCode = sysUser.getStationCode();
        
        // 生成身份证号
        String idCard = generateIdCard(stationCode, birthRegistrationBO.getBirthDate(), birthRegistrationBO.getChildGender());
        personInfo.setIdCard(idCard);

        int i = personInfoMapper.insert(personInfo);
        if (i <= 0) {
            return GraceJSONResult.errorMsg("插入人员信息失败");
        }

        HouseholdTransfer householdTransfer = new HouseholdTransfer();
        householdTransfer.setPersonId(personInfo.getId());
        householdTransfer.setTargetHouseholdId(birthRegistration.getTargetHouseholdId());
        householdTransfer.setTransferReason("新生儿出生入户");
        householdTransfer.setApplicationDate(new Date());
        householdTransfer.setApplicationStatus((byte)1);
        householdTransfer.setCreateTime(new Date());
        householdTransfer.setUpdateTime(new Date());
        householdTransfer.setCreateBy(sysUser.getId());
        householdTransfer.setUpdateBy(sysUser.getId());

        if (personInfo.getGender() == 1){
            householdTransfer.setRelationship("子");
        }else if (personInfo.getGender() == 2){
            householdTransfer.setRelationship("女");
        }

        householdTransferMapper.insert(householdTransfer);

        boolean result = this.save(birthRegistration);
        if (result) {
            return GraceJSONResult.ok();
        }else {
            return GraceJSONResult.errorMsg("出生申报失败");
        }
    }

    /**
     * 生成身份证号
     * @param stationCode 地区代码（6位）
     * @param birthDate 出生日期
     * @param gender 性别：1-男，2-女
     * @return 18位身份证号
     */
    private String generateIdCard(String stationCode, Date birthDate, Byte gender) {
        // 1. 地区代码（前6位）
        String areaCode = stationCode;

        // 2. 出生日期（第7-14位）YYYYMMDD
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        String birthDateStr = dateFormat.format(birthDate);

        // 3. 顺序码（第15-17位）
        // 使用Redis生成当天的顺序号，确保唯一性
        String dateKey = "idcard_seq:" + areaCode + ":" + birthDateStr;
        Long sequence = redisTemplate.opsForValue().increment(dateKey);

        // 根据性别调整顺序码：奇数为男，偶数为女
        int sequenceNum = sequence.intValue();
        if (gender == 1) { // 男性，确保为奇数
            if (sequenceNum % 2 == 0) {
                sequenceNum++;
            }
        } else { // 女性，确保为偶数
            if (sequenceNum % 2 == 1) {
                sequenceNum++;
            }
        }

        // 格式化为3位数字，不足补0
        String sequenceStr = String.format("%03d", sequenceNum);

        // 4. 前17位
        String front17 = areaCode + birthDateStr + sequenceStr;

        // 5. 计算校验码（第18位）
        String checkCode = calculateCheckCode(front17);

        return front17 + checkCode;
    }


    private String calculateCheckCode(String front17) {
        // 权重数组
        int[] weights = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
        // 校验码对应表
        String[] checkCodes = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};

        int sum = 0;
        for (int i = 0; i < 17; i++) {
            // 使用更简单的方式将字符转换为数字，兼容JDK17
            int digit = Character.getNumericValue(front17.charAt(i));
            sum += digit * weights[i];
        }

        int remainder = sum % 11;
        return checkCodes[remainder];
    }

}



